#include "config.h"
#include "led.h"
#include "UART.h"
#include "GPIO.h"
#include "DHT11.h"
#include "PCF8563.h"
#include "oled.h"
#include "I2C.h"
#include "Motors.h"
#include "Ultrasonic.h"
#include  "BMP.h"

// 定义各个模块的任务块
#define LED 2
#define LED_OFF 3
#define DHT11 4
#define TIMER 5
#define MOTORQ 6
#define MOTORH 7
#define FINE 8


// 定义OLED屏幕的字体尺寸
#define	FONT_H	16
// 初始化GPIO引脚P32 P33 OLED屏幕需要用到I2C,I2C的需要用到这两个引脚
void GPIO_config(void) {
    GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义
    GPIO_InitStructure.Pin  = GPIO_Pin_2 | GPIO_Pin_3;		//指定要初始化的IO,
    GPIO_InitStructure.Mode = GPIO_OUT_OD;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);//初始化
}

// 初始化调试用的UART串口1
void UART_config(void) {
    // >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<
    COMx_InitDefine		COMx_InitStructure;					//结构定义
    COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
    COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200
    COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLE
    COMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLE
    UART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4

    NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}

// 初始化语音模块用的UART串口2
void UART2_config(void) {
    COMx_InitDefine		COMx_InitStructure;					//结构定义
    COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    COMx_InitStructure.UART_BRT_Use   = BRT_Timer2;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
    COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200
    COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLE
    COMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLE
    UART_Configuration(UART2, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4

    NVIC_UART2_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    UART2_SW(UART2_SW_P10_P11);		// 引脚选择, UART2_SW_P10_P11,UART2_SW_P46_P47
}

// 初始化I2C
void	I2C_config(void)
{
    I2C_InitTypeDef		I2C_InitStructure;

    I2C_InitStructure.I2C_Mode      = I2C_Mode_Master;	//主从选择   I2C_Mode_Master, I2C_Mode_Slave
    I2C_InitStructure.I2C_Enable    = ENABLE;			//I2C功能使能,   ENABLE, DISABLE
    I2C_InitStructure.I2C_MS_WDTA   = DISABLE;			//主机使能自动发送,  ENABLE, DISABLE
    I2C_InitStructure.I2C_Speed     = 13;				//总线速度=Fosc/2/(Speed*2+4),      0~63
    // 400k, 24M => 13
    I2C_Init(&I2C_InitStructure);
    NVIC_I2C_Init(I2C_Mode_Master,DISABLE,Priority_0);	//主从模式, I2C_Mode_Master, I2C_Mode_Slave; 中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

    I2C_SW(I2C_P33_P32);					//I2C_P14_P15,I2C_P24_P25,I2C_P33_P32
}

// 调用所有初始化函数
void sys_init() {
	
    EAXSFR();
    GPIO_config();
    UART_config();
    UART2_config();
    I2C_config();

    // LED灯初始化
    LED_INIT();
//    LED_Switch(1);

    // 温湿度初始化
    DHT11_init();

    // 定时器初始化
    PCF8563_init();

    // OLED屏幕初始化
    OLED_Init();
		
		OLED_DisplayTurn(1);//0正常显示 1 屏幕翻转显示
		OLED_DrawBMP(0,0,128,64,BMP1);
		// 电机初始化
		Motors_init();
		
    EA = 1;
}

/*
	根据串口接收的数据,使用相应功能
*/
void judgment(void) {
    u8 dat = RX2_Buffer[0];
    // printf("%d\n",(int)RX2_Buffer[0]);
    if(RX2_Buffer[0] ==LED) {
        LED_Switch(1);
        os_create_task(LED);// 创建灯任务
 
    }
    if (RX2_Buffer[0] == LED_OFF) {
        LED_Switch(0);
        os_delete_task(LED);// 销毁灯任务

    }
    if (RX2_Buffer[0] == DHT11) {

        os_delete_task(TIMER);// 销毁定时器任务
        os_send_signal(DHT11);// 唤醒温湿度任务

    }
    if (RX2_Buffer[0] == TIMER) {

        os_delete_task(TIMER);// 销毁定时器任务
        os_create_task(TIMER);// 创建定时器任务

    }
		if( RX2_Buffer[0] == MOTORQ) {
				printf("%d",(int)RX2_Buffer[0]);
        os_create_task(MOTORQ);
			
		}
		if( RX2_Buffer[0] == MOTORH) {
				printf("%d",(int)RX2_Buffer[0]);
        os_create_task(MOTORH);
				
		}
    if( RX2_Buffer[0] == FINE) {

        // printf("删除任务成功");
				LED_Switch(0);// 关灯
				OLED_Clear();// 清空屏幕
				os_delete_task(TIMER);// 销毁时间任务
				os_delete_task(LED);// 销毁灯任务
				os_delete_task(MOTORQ);// 销毁小车前进任务
				os_delete_task(MOTORH);// 销毁小车后退任务
        OLED_DrawBMP(0,0,128,64,BMP1);
        

    }
}

void start_main() _task_ 0 {

    sys_init();

    // 创建任务
    os_create_task(1);

    // 创建温湿度任务
    os_create_task(DHT11);

    // 销毁自己
    os_delete_task(0);

}
// 主任务
void task_key() _task_ 1 {
    // printf("初始化");

    while(1) {
				// UART2接收数据
        if(COM2.RX_TimeOut > 0) {
            //超时计数
            if(--COM2.RX_TimeOut == 0) {
                if(COM2.RX_Cnt > 0) {
                    judgment();
                }
                COM2.RX_Cnt = 0;
            }
        }
        os_wait2(K_TMO,1);
    }
}

// 实现LED
void LED_TASK() _task_ LED {
    LED_ALL_ON(0);
    while(1) {
        LED_ALL_ON(1);
        os_wait2(K_TMO,1);
    }

}
// 实现获取温湿度
void DHT11_TASK() _task_ DHT11 {

    u8 humidity;
    float temperature = 0.0;

    while(1) {
        os_wait1(K_SIG);// 延迟

        DHT11_get_info( &humidity,&temperature);// 调用获取温度和适度函数
        printf("humidity: %d temperature: %.2f\n", (int)humidity, temperature);

        OLED_Clear();
				
				// OLED屏幕显示
        OLED_ShowChinese(0,0,2,16);
        OLED_ShowChinese(18,0,1,16);
        OLED_ShowNum(40,0,humidity,3,16);
        OLED_ShowString(66,0,"F",16);

        OLED_ShowChinese(0,4,0,16);
        OLED_ShowChinese(18,4,1,16);
        OLED_ShowNum(40,4,temperature,3,16);
        OLED_ShowString(66,4,"C",16);
    }

}
// 实现获取时间
void TIMER_TASK() _task_ TIMER {
    Clock_t c;
    char timeString[10];
    c.year = 2023, c.month = 10, c.day = 15, c.week = 6;
	c.hour = 20, c.minute = 40, c.second = 00;
	// PCF8563_set_clock(c);// 已经设置过时间,请勿重复设置调用设置时间函数

    OLED_Clear();
    while(1) {

        PCF8563_get_clock(&c);// 调用获取时间函数
         printf("%d-%d-%d ", (int)c.year, (int)c.month, (int)c.day);
         printf("%d:%d:%d ", (int)c.hour, (int)c.minute, (int)c.second);
         printf("week->%d \n", (int)c.week);

        OLED_ShowNum(0, 0, c.year, 4, FONT_H);// 调用OLED显示数字函数
        OLED_ShowChar(32, 0, '-', FONT_H);// 调用OLED显示字符串函数
        if(c.month < 10) {	// 1位,前边加0
            OLED_ShowNum(32 + 8, 0, 0, 1, FONT_H);
            OLED_ShowNum(32 +16, 0, c.month, 1, FONT_H);
        } else {
            OLED_ShowNum(32 + 8, 0, c.month, 2, FONT_H);
        }
        OLED_ShowChar(56, 0, '-', FONT_H);
        if(c.day < 10) {
            OLED_ShowNum(56 + 8, 0, 0, 1, FONT_H);
            OLED_ShowNum(56 +16, 0, c.day, 1, FONT_H);
        } else {
            OLED_ShowNum(56 + 8, 0, c.day, 2, FONT_H);
        }

        // sprintf(timeString, "%d-%d", (int)c.year, (int)c.month);
        // OLED_ShowString(0, 0, timeString, FONT_H);

        sprintf(timeString, "%d:%d:%d", (int)c.hour, (int)c.minute, (int)c.second);// 拼接时:分:秒
        OLED_ShowString(0, 2, timeString, FONT_H);// 调用OLED显示字符串函数

        os_wait2(K_TMO,200);// 延迟1s
    }

}
// 实现小车前进
void MOTORQ_TASK() _task_ MOTORQ {
    while(1) {
        Motors_forward(50);// 调用前进函数,速度为50
        os_wait2(K_TMO,200);// 延迟1s
				Motors_stop();// 调用停止函数
				os_delete_task(MOTORQ);// 销毁前进任务
    }
}
// 实现小车后退
void MOTORH_TASK() _task_ MOTORH {
    while(1) {
        Motors_backward(50);// 调用后退函数,速度为50
        os_wait2(K_TMO,200);// 延迟1s
				Motors_stop();// 调用停止函数
				os_delete_task(MOTORH);// 销毁后退任务
    }
}
